package com.xuan.yubi.bizmq;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.rabbitmq.client.Channel;
import com.xuan.yubi.common.ErrorCode;
import com.xuan.yubi.constant.ChartStatusConstant;
import com.xuan.yubi.constant.RabbitMqConstant;
import com.xuan.yubi.exception.BusinessException;
import com.xuan.yubi.manager.XunFeiAiManager;
import com.xuan.yubi.model.entity.Chart;
import com.xuan.yubi.service.ChartService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;


@Component
@Slf4j
public class BiMessageConsumer {

    @Resource
    private ChartService chartService;

    @Resource
    private XunFeiAiManager xunFeiAiManager;

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;


    // RejectedExecutionException

    @SneakyThrows
    @RabbitListener(queues = {RabbitMqConstant.QUEUE_NAME}, ackMode = "MANUAL")
    public void receiveMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliverTag) {
        log.info("[receiveMessage] receiveMessage message:{}", message);

        CompletableFuture.runAsync(() -> {
            // 1. 确认图表信息是否存在
            if (StringUtils.isBlank(message)) {
                try {
                    channel.basicNack(deliverTag, false, false);
                } catch (IOException e) {
                    log.error("nack error: ", e);
                }
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "消息为空");
            }
            long chartId = Long.parseLong(message);
            Chart chart = chartService.getById(chartId);
            if (chart == null) {
                try {
                    channel.basicNack(deliverTag, false, false);
                } catch (IOException e) {
                    log.error("nack error: ", e);
                }
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "消息为空");
            }

            String goal = chart.getGoal();
            String chartType = chart.getChartType();
            String csvData = chart.getChartData();
            try {
                // 2. 构造用户输入
                // 1) 拼接用户分析需求和期望图表类型(若存在)
                StringBuilder userInput = new StringBuilder();
                userInput.append("分析需求:").append('\n');
                String userGoal = goal;
                if (StringUtils.isNotBlank(chartType)) {
                    userGoal += ", 请使用" + chartType;
                }
                userInput.append(userGoal).append('\n');
                // 2) 拼接压缩后的原始数据
                userInput.append("原始数据:").append("\n");
                userInput.append(csvData);

                // 3. 调用 AI分析服务 并实时修改图表生成状态
                // 1) 将任务执行状态修改为"running"
                chart.setChartStatus(ChartStatusConstant.RUNNING);
                boolean b = chartService.updateById(chart);
                if (!b) {
                    handleUpdateChartError(chartId, "更新图表执行中状态失败", channel, deliverTag);
                }
                // 2)调用 AI 分析服务
                System.out.println(userInput);
                String result = xunFeiAiManager.doChat(userInput.toString());
                System.out.println(result);
                String[] split = result.split("【【【【【");
                if (split.length < 3) {
                    handleUpdateChartError(chartId, "AI 生成错误", channel, deliverTag);
                }
                // 对生成的 option 对象进行解析校验
                String genChart = split[1].trim();
                String genResult = split[2].trim();
                try {
                    JSONObject jsonObject = JSONUtil.parseObj(genChart);
                    genChart = jsonObject.toString();
                } catch (Exception e) {
                    handleUpdateChartError(chartId, "AI 生成错误", channel, deliverTag);
                }

                chart.setChartStatus(ChartStatusConstant.SUCCEED);
                chart.setGenChart(genChart);
                chart.setGenResult(genResult);
                b = chartService.updateById(chart);
                if (!b) {
                    handleUpdateChartError(chartId, "更新图表成功状态失败", channel, deliverTag);
                }

                channel.basicAck(deliverTag, false);
            } catch (IOException e) {
                log.error("confirm message error: ", e);
            }
        }, threadPoolExecutor);

    }


    /**
     * 保存图表生成过程中的错误信息
     *
     * @param chartId
     * @param exeMessage
     */
    private void handleUpdateChartError(Long chartId, String exeMessage, Channel channel, long deliverTag) {
        Chart updateChart = new Chart();
        updateChart.setId(chartId);
        updateChart.setChartStatus(ChartStatusConstant.FAIL);
        updateChart.setExeMessage(exeMessage);
        chartService.updateById(updateChart);
        try {
            channel.basicNack(deliverTag, false, false);
        } catch (IOException e) {
            log.error("nack error, chartId:{}", chartId, e);
        }
        throw new BusinessException(ErrorCode.SYSTEM_ERROR, exeMessage);
    }


    public static void main(String[] args) throws JsonProcessingException {
        String jsonStr = "{\n" +
                "    title: {\n" +
                "        text: '网页用户增长趋势'\n" +
                "    },\n" +
                "    tooltip: {},\n" +
                "    legend: {\n" +
                "        data: ['网站访问量']\n" +
                "    },\n" +
                "    xAxis: {\n" +
                "        type: 'category',\n" +
                "        data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50']\n" +
                "    },\n" +
                "    yAxis: {},\n" +
                "    series: [{\n" +
                "        name: '网站访问量',\n" +
                "        type: 'line',\n" +
                "        data: [3650, 450, 100, 800, 600, 750, 50, 800, 200, 400, 550, 0, 850, 900, 100, 750, 250, 550, 800, 0, 350, 750, 100, 650, 550, 0, 950, 200, 150, 300, 850, 100, 600, 950, 200, 800, 0, 650, 900, 150, 600, 50, 750, 800, 100, 950, 200, 850, 100, 600]\n" +
                "    }]\n" +
                "}";
        JSON json = JSONUtil.parse(jsonStr);
        System.out.println(jsonStr);
        System.out.println(json.toString());
        System.out.println(json.toStringPretty());

    }
}
